package org.example.rubbish.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.rubbish.dto.AlarmDTO;
import org.example.rubbish.entity.Alarm;
import org.example.rubbish.mapper.AlarmMapper;
import org.example.rubbish.service.AlarmService;
import org.example.rubbish.service.UnifiedWebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AlarmServiceImpl implements AlarmService {

    @Autowired
    private AlarmMapper alarmMapper;

    @Autowired
    private UnifiedWebSocketService unifiedWebSocketService;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    @Transactional
    public boolean processNewAlarm(AlarmDTO alarmDTO) {
        try {
            // 创建报警实体
            Alarm alarm = new Alarm();
            alarm.setAlarmId(alarmDTO.getAlarmId() != null ? alarmDTO.getAlarmId() :
                    generateAlarmId());
            alarm.setTitle(alarmDTO.getTitle());
            alarm.setContent(alarmDTO.getContent());
            alarm.setSource(alarmDTO.getSource());
            alarm.setLevel(alarmDTO.getLevel());
            alarm.setType(alarmDTO.getType());
            alarm.setAcknowledged(false);
            alarm.setCreateTime(LocalDateTime.now());
            alarm.setUpdateTime(LocalDateTime.now());

            // 转换扩展信息为JSON
            if (alarmDTO.getExtraData() != null) {
                alarm.setExtraInfo(objectMapper.writeValueAsString(alarmDTO.getExtraData()));
            }

            // 保存到数据库
            alarmMapper.insert(alarm);

            unifiedWebSocketService.broadcastAlarm(alarmDTO);


        } catch (JsonProcessingException e) {
            throw new RuntimeException("报警数据处理失败", e);
        } catch (Exception e) {
            throw new RuntimeException("处理新报警失败", e);
        }
        return false;
    }

    @Override
    @Transactional
    public boolean acknowledgeAlarm(String alarmId, String acknowledgedBy) {
        try {
            Alarm alarm = new Alarm();
            alarm.setAlarmId(alarmId);
            alarm.setAcknowledged(true);
            alarm.setAcknowledgedBy(acknowledgedBy);
            alarm.setAcknowledgedTime(LocalDateTime.now());
            alarm.setUpdateTime(LocalDateTime.now());

            int result = alarmMapper.updateAcknowledgedStatus(alarm);

            if (result > 0) {

                // 通过统一WebSocket服务广播确认消息给所有客户端
                unifiedWebSocketService.broadcastAcknowledgment(alarmId, acknowledgedBy);

                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public List<Alarm> getUnacknowledgedAlarms() {
        return alarmMapper.selectByAcknowledgedStatus(false);
    }

    @Override
    public List<Alarm> getAlarmsBySource(String source, int hours) {
        LocalDateTime startTime = LocalDateTime.now().minusHours(hours);
        return alarmMapper.selectBySourceAndTime(source, startTime);
    }

    @Override
    public AlarmStatistics getAlarmStatistics() {
        AlarmStatistics stats = new AlarmStatistics();
        stats.setTotalUnacknowledged(alarmMapper.countUnacknowledgedAlarms());
        // 可以添加更多统计逻辑
        return stats;
    }

    private String generateAlarmId() {
        return "ALARM_" + System.currentTimeMillis() + "_" +
                UUID.randomUUID().toString().substring(0, 8);
    }
    public List<AlarmDTO> getAlarmsFromDatabase(Integer hours, Boolean acknowledged, Integer limit, String source, String level) {
        try {
            // 构建查询条件
            LocalDateTime startTime = hours != null ? LocalDateTime.now().minusHours(hours) : null;

            // 这里使用您XML中已有的复杂查询方法
            Map<String, Object> queryParams = new java.util.HashMap<>();

            if (acknowledged != null) {
                queryParams.put("acknowledged", acknowledged);
            }
            if (source != null && !source.isEmpty()) {
                queryParams.put("source", source);
            }
            if (level != null && !level.isEmpty()) {
                queryParams.put("level", level);
            }
            if (startTime != null) {
                queryParams.put("startTime", startTime);
            }
            if (limit != null && limit > 0) {
                queryParams.put("limit", limit);
            }

            // 使用XML中的selectComplexQuery方法
            List<Alarm> alarms = alarmMapper.selectComplexQuery(queryParams);

            // 转换为DTO
            return alarms.stream()
                    .map(this::convertAlarmToDTO)
                    .collect(Collectors.toList());

        } catch (Exception e) {
            throw new RuntimeException("获取报警数据失败", e);
        }
    }

    @Override
    public List<AlarmDTO> getRecentUnacknowledgedAlarms(int hours) {
        try {
            LocalDateTime startTime = LocalDateTime.now().minusHours(hours);
            Map<String, Object> queryParams = new java.util.HashMap<>();
            queryParams.put("acknowledged", false);
            queryParams.put("startTime", startTime);
            queryParams.put("limit", 100); // 限制100条

            List<Alarm> alarms = alarmMapper.selectComplexQuery(queryParams);
            return alarms.stream()
                    .map(this::convertAlarmToDTO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            throw new RuntimeException("获取最近未确认报警失败", e);
        }
    }

    @Override
    public AlarmDTO convertAlarmToDTO(Alarm alarm) {
        try {
            AlarmDTO dto = new AlarmDTO();
            dto.setAlarmId(alarm.getAlarmId());
            dto.setTitle(alarm.getTitle());
            dto.setContent(alarm.getContent());
            dto.setSource(alarm.getSource());
            dto.setLevel(alarm.getLevel());
            dto.setType(alarm.getType());
            dto.setTimestamp(alarm.getCreateTime()); // 使用创建时间作为时间戳

            // 转换扩展信息
            if (alarm.getExtraInfo() != null && !alarm.getExtraInfo().isEmpty()) {
                try {
                    @SuppressWarnings("unchecked")
                    Map<String, Object> extraData = objectMapper.readValue(alarm.getExtraInfo(), Map.class);
                    dto.setExtraData(extraData);
                } catch (JsonProcessingException e) {
                    // 如果解析失败，将原始字符串作为extraData
                    dto.setExtraData(Map.of("rawInfo", alarm.getExtraInfo()));
                }
            }

            return dto;
        } catch (Exception e) {
            throw new RuntimeException("报警数据转换失败", e);
        }
    }

    public static class AlarmStatistics {
        private int totalUnacknowledged;
        private int highLevelCount;
        private int criticalLevelCount;

        public AlarmStatistics() {
        }

        public AlarmStatistics(int totalUnacknowledged, int highLevelCount, int criticalLevelCount) {
            this.totalUnacknowledged = totalUnacknowledged;
            this.highLevelCount = highLevelCount;
            this.criticalLevelCount = criticalLevelCount;
        }

        public int getTotalUnacknowledged() {
            return totalUnacknowledged;
        }

        public void setTotalUnacknowledged(int totalUnacknowledged) {
            this.totalUnacknowledged = totalUnacknowledged;
        }

        public int getHighLevelCount() {
            return highLevelCount;
        }

        public void setHighLevelCount(int highLevelCount) {
            this.highLevelCount = highLevelCount;
        }

        public int getCriticalLevelCount() {
            return criticalLevelCount;
        }

        public void setCriticalLevelCount(int criticalLevelCount) {
            this.criticalLevelCount = criticalLevelCount;
        }
    }
}